package models

import (
	"chat/utils"
	"strconv"
	"time"

	"gorm.io/gorm"
)

type UserBasic struct {
	gorm.Model
	Name            string    `json:"username" gorm:"账户名(唯一)"`
	PassWord        string    `json:"password" gorm:"用户密码"`
	Phone           string    `josn:"phone" valid:"matches(^1[3-9]{1}\\d{9}$)" gorm:"手机号"`
	Email           string    `json:"email" valid:"email" gorm:"邮箱"`
	Identity        string    `json:"identity"  gorm:"忘记干嘛用的了"`
	ClientIP        string    `json:"client_ip" gorm:"用户登录IP"`
	ClientPort      string    `json:"client_port" gorm:"用户登录端口"`
	Salt            string    `json:"salt" gorm:"用户密码加解密字段"`
	LoginTime       time.Time `json:"login_time" gorm:"最近登录时间"`
	HeartbeatTime   time.Time `json:"heartbeat_time" gorm:"最近活跃时间"`
	LogoutTime      time.Time `json:"logout_time" gorm:"登出时间"`
	DeviceInfo      string    `json:"device_info" gorm:"用户登录设备信息"`
	Type            int       `json:"type"  gorm:"账号状态"` //  1：正常使用 2：已删除 3：注销
	IsLogin         bool      `json:"is_login"  gorm:"是否登录"`
	LastLoginAction string    `json:"action" gorm:"忘记干嘛用的了"`
	Avatar          string    `json:"avatar"  gorm:"头像"`
	NickName        string    `json:"nickname"  gorm:"昵称"`
	Birthday        string    `json:"birthday"  gorm:"出身日期，时间戳格式存储"`
	Local           string    `json:"local"   gorm:"详细地址"`
	Gender          string    `json:"gender" gorm:"性别"`
	Signature       string    `json:"signature" gorm:"个性签名"`
}

func (table *UserBasic) TableName() string {
	return "user_basic"
}

type contactInfo struct {
	UserBasic
	IsUser          bool   `json:"is_user"`
	LastChatContent string `json:"last_chat_content"`
	LastChatTime    string `json:"last_chat_time"`
	NotReadChat     int    `json:"not_read_chat"`
	OwnerId         uint   `json:"owner_id"`
	OwnerName       string `json:"owner_name"`
	Icon            string `json:"icon"`
}

func RectifyConentType(media int, content string, item *contactInfo) {
	switch media {
	case 1:
		item.LastChatContent = content
	case 2:
		item.LastChatContent = "[动画表情]"
	case 3:
		item.LastChatContent = "[图片]"
	case 4:
		item.LastChatContent = "[文件]"
	case 5:
		item.LastChatContent = "[语音信息]"

	}
}
func GetUserList(id string) (interface{}, error) {
	var users []*contactInfo
	var groups []*contactInfo
	if err := utils.Mysql.Table("contact_basic").
		Select("user_basic.*").
		Joins("JOIN user_basic ON contact_basic.owner_id = user_basic.id OR contact_basic.target_id = user_basic.id").
		Where("contact_basic.agree_or_not = '1' AND (contact_basic.owner_id = ? OR contact_basic.target_id = ?)  ", id, id).
		Find(&users).Error; err != nil {
		return nil, err
	}
	if err := utils.Mysql.Table("contact_basic").
		Select("group_basic.*").
		Joins("JOIN group_basic ON contact_basic.target_id = group_basic.id   AND contact_basic.type = 2").
		Joins("JOIN user_basic ON  user_basic.id = group_basic.owner_id").
		Where("contact_basic.owner_id = ? ", id).
		Find(&groups).Error; err != nil {
		return nil, err
	}

	for i, v := range groups {
		var lenght int
		msg, err := GetLastHistory(id, strconv.FormatUint(uint64(v.ID), 10), "2")
		GetHistoryGroupNotRead(id, &lenght)
		groups[i].IsUser = false
		if err != nil {
			groups[i].LastChatContent = ""
			groups[i].LastChatTime = ""
			groups[i].NotReadChat = 0
		} else {
			duration := time.Since(msg.SendTime)
			days := int(duration.Hours() / 24)
			localSendTime := msg.SendTime.In(time.Local)
			switch {
			case days < 1:
				groups[i].LastChatTime = localSendTime.Format("15:04") // 显示时分
			case days == 1:
				groups[i].LastChatTime = "昨天"
			default:
				groups[i].LastChatTime = localSendTime.Format("2006-01-02") // 显示年月日
			}
		}
		groups[i].NotReadChat = lenght
		RectifyConentType(msg.Media, msg.Content, groups[i])
		// if msg.Media == 1 {
		// 	groups[i].LastChatContent = msg.Content
		// } else if msg.Media == 2 {
		// 	groups[i].LastChatContent = "[动画表情]"
		// } else if msg.Media == 3 {
		// 	groups[i].LastChatContent = "[图片]"
		// } else if msg.Media == 4 {
		// 	groups[i].LastChatContent = "[文件]"
		// } else if msg.Media == 5 {
		// 	groups[i].LastChatContent = "[语音信息]"
		// }
	}
	for i, v := range users {
		var lenght int
		msg, err := GetLastHistory(id, strconv.FormatUint(uint64(v.ID), 10), "1")
		GetHistoryUserNotRead(id, strconv.FormatUint(uint64(v.ID), 10), &lenght)

		users[i].IsUser = true
		if err != nil {
			users[i].LastChatContent = ""
			users[i].LastChatTime = ""
			users[i].NotReadChat = 0
		} else {
			duration := time.Since(msg.SendTime)
			days := int(duration.Hours() / 24)
			localSendTime := msg.SendTime.In(time.Local)
			switch {
			case days < 1:
				users[i].LastChatTime = localSendTime.Format("15:04") // 显示时分
			case days == 1:
				users[i].LastChatTime = "昨天"
			default:
				users[i].LastChatTime = localSendTime.Format("2006-01-02") // 显示年月日
			}
		}
		users[i].NotReadChat = lenght
		RectifyConentType(msg.Media, msg.Content, users[i])
		// if msg.Media == 1 {
		// 	users[i].LastChatContent = msg.Content
		// } else if msg.Media == 2 {
		// 	users[i].LastChatContent = "[动画表情]"
		// } else if msg.Media == 3 {
		// 	users[i].LastChatContent = "[图片]"
		// } else if msg.Media == 4 {
		// 	users[i].LastChatContent = "[文件]"
		// } else if msg.Media == 5 {
		// 	users[i].LastChatContent = "[语音信息]"
		// }
	}
	return append(users, groups...), nil
}

func CreateUser(user *UserBasic) error {
	return utils.Mysql.Create(&user).Error
}

func FindUserByID(id string) (UserBasic, error) {
	user := UserBasic{}
	err := utils.Mysql.Where("id = ?", id).First(&user).Error
	return user, err
}
func FindUserByName(name string) (UserBasic, error) {
	user := UserBasic{}
	err := utils.Mysql.Where("name = ?", name).First(&user).Error
	return user, err
}

func FindUserByPhone(phone string) (UserBasic, error) {
	user := UserBasic{}
	err := utils.Mysql.Where("phone = ?", phone).First(&user).Error
	return user, err
}

func FindUserByEmail(email string) (UserBasic, error) {
	user := UserBasic{}
	err := utils.Mysql.Where("email = ?", email).First(&user).Error
	return user, err
}

func removal(users []*UserBasic) []*UserBasic {
	result := make([]*UserBasic, 0)
	uniqueMap := make(map[string]struct{}) // 存放唯一值的 map

	for _, user := range users {
		key := user.Name + user.Email + user.Phone
		if _, ok := uniqueMap[key]; !ok {
			uniqueMap[key] = struct{}{}
			result = append(result, user)
		}
	}
	return result
}

func FindNewFriends(name string) ([]*UserBasic, error) {
	names := make([]*UserBasic, 0)
	if err := utils.Mysql.Table("user_basic").Where("name LIKE ? ", "%"+name+"%").Find(&names).Error; err != nil {
		return nil, err
	}
	phones := make([]*UserBasic, 0)
	if err := utils.Mysql.Table("user_basic").Where("phone LIKE ? ", "%"+name+"%").Find(&phones).Error; err != nil {
		return nil, err
	}

	emails := make([]*UserBasic, 0)
	if err := utils.Mysql.Table("user_basic").Where("email LIKE ? ", "%"+name+"%").Find(&emails).Error; err != nil {
		return nil, err
	}
	data := append(append(names, phones...), emails...)
	res := removal(data)
	return res, nil
}

func UpdateUser(user *UserBasic) error {

	return utils.Mysql.Model(user).Updates(user).Error
}
